package base.transporte;

import java.util.concurrent.atomic.AtomicBoolean;

public class EnviaPacote implements Runnable {
	SRPacket pacote;
	SRSocket conector;
	AtomicBoolean done;
	AtomicBoolean ackChegou;
	EstimadorRTT estimadorRTT;

	public EnviaPacote(SRPacket pacote, SRSocket conector, EstimadorRTT estimadorRTT) {
		this.pacote = pacote;
		this.conector = conector;
		done = new AtomicBoolean(false);
		ackChegou = new AtomicBoolean(false);
		this.estimadorRTT = estimadorRTT;
	}

	public SRPacket getPacote() {
		return this.pacote;
	}

	public void alertaChegadaDeAck() {
		synchronized (this) {

			ackChegou.set(true);
			done.set(true);
			this.notifyAll();
		}
	}

	public boolean isDone() {
		boolean retorno;

		retorno = done.get();

		return retorno;
	}

	@Override
	public void run() {
		conector.inserirAckAEsperar(pacote.getSeqNum(), this);
		long startTime = System.currentTimeMillis();

		long timeOut = estimadorRTT.getTimeoutInterval();
		try {
			conector.sendPacket(pacote);
		} catch (Exception e) {
			e.printStackTrace();
		}

		synchronized (this) {
			while (ackChegou.get() == false) {
				try {
					if (ackChegou.get() == false)
						conector.sendPacket(pacote);
				} catch (Exception e) {
					e.printStackTrace();
				}

				if (ackChegou.get() == false) {
					try {
						this.wait(timeOut);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}

		long endTime = System.currentTimeMillis();
		estimadorRTT.insertSample(endTime - startTime);
	}

}
